package com.alone.jpa.entity.support;

import cn.hutool.core.collection.CollUtil;
import lombok.experimental.UtilityClass;

import javax.persistence.MappedSuperclass;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Alone
 */
@UtilityClass
public class EntityFieldsCache {

    private static final Map<Class<?>, List<Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();

    public List<Field> getFields(Class<?> clazz) {
        List<Field> fields = CLASS_FIELD_CACHE.get(clazz);
        if (fields != null) {
            return fields;
        }
        fields = doGetFields(clazz);
        CLASS_FIELD_CACHE.put(clazz, fields);
        return fields;
    }

    private List<Field> doGetFields(Class<?> clazz) {
        List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
        for (Field field : fields) {
            field.setAccessible(true);
        }
        Class<?> superclass = clazz.getSuperclass();
        boolean isMappedSuperClass = superclass.isAnnotationPresent(MappedSuperclass.class);
        if (isMappedSuperClass) {
            List<Field> superFields = doGetFields(superclass);
            return CollUtil.unionAll(fields, superFields);
        }
        return fields;
    }

}
